package com.movisol.adsservice.client;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import com.movisol.adsservice.client.events.AdLoadEvent;
import com.movisol.adsservice.client.events.AdsLoadEvent;
import com.movisol.adsservice.client.listeners.OnAdLoadedListener;
import com.movisol.adsservice.client.listeners.OnAdsLoadedListener;

public class BannerSlotManager implements OnAdsLoadedListener{

	private double weight;
	private Timer t;
	private Ad ad;
	private BannerSlot bs;
	private int id;
	private boolean prepared=false;
	protected List listeners = new ArrayList();
	private AdsManager am = AdsManager.getInstance();
	public boolean suspend=false;
	private final static int WAIT_TIME_TO_REQUEST = 30000;
	public BannerSlotManager(int id) {
		this.id=id;
		am.addOnAdsLoadedListener(this);
	}
	
	public synchronized void addOnAdLoadedListener(OnAdLoadedListener listener){
		listeners.add(listener);
	}
	public synchronized void removeAdLoadedListener(OnAdLoadedListener listener){
		listeners.remove(listener);
	}
	public synchronized void fireAdLoadEvent(){
		AdLoadEvent adEvt = new AdLoadEvent(this,ad);
		ListIterator it = listeners.listIterator();
		while (it.hasNext()){
			
			((OnAdLoadedListener) it.next()).onAdLoaded(adEvt);
		}

	}
	/**
	 * 
	 * @param inner true para solicitar ads de movisol exclusivamente false para todos
	 */
	private void getCurrAdd(boolean inner){
	 if (am.adsLoaded()){
		 
		  if (!prepared) 
			  prepareBanerSlot();
		  
		  if(prepared)
		  {
		   setCurrentAd(inner);
		   
		 	if (ad!=null ){		 	
		 		fireAdLoadEvent();
		 	}
		  }
	 	}
	}
	
    public  void timerStart()
    {
    	TimerTask askForAd = new TimerTask() {
			
			@Override
			public void run() {
				
				if (!suspend) 
					getCurrAdd(false);
			}
		};
		
		t = new Timer();
   
	    synchronized (t)
	    {
	    	t.scheduleAtFixedRate(askForAd, 0, WAIT_TIME_TO_REQUEST);
	    }
    }
	
    private void prepareBanerSlot (){
    
    	if(am.getBannerSlotbyID(id) != null)
    	{
    		bs = am.getBannerSlotbyID(id);
    	
    	// Primero calculamos el peso total del BanerSlot
		Iterator<AdBanner> itFirst = bs.getAdBanerList().iterator();
		while (itFirst.hasNext()) {
			Ad currAd = itFirst.next();
			weight = weight + currAd.getWeight();
		}
		
		
		// Despues calculamos el porcentaje de exposicion y rellenamos la lista
		// de AddBaners

		Iterator<AdBanner> itSecond = bs.getAdBanerList().iterator();
		//Porcentaje de exposicion acumulado
		double acuExpValue=0;
		while (itSecond.hasNext()) {

			AdBanner adBanner = (AdBanner) itSecond.next();
			acuExpValue = acuExpValue + adBanner.getWeight() / weight;
			adBanner.setExpValue(acuExpValue);
	
			prepared=true;
    }
    	}
    	else
    		prepared = false;
		
   }
    private void setCurrentAd(boolean inner){
    	AdBanner bestAd =null;
		Random r = new Random();
		//Obtenemos un random entre 0 y 1 y devolvemos el que mayor valor de exposicion tenga de los menores al numero obtenido
		Iterator<AdBanner> it= bs.getAdBanerList().iterator();
		if (!inner)		
		{
			double randomVal=(double) r.nextInt(100);
			randomVal=randomVal/100;
	
			while (it.hasNext())
			{
				AdBanner actAdb = it.next();
				//Si la peticion es de tipo inner no se deben contar los adds de tipo Admob 99
				if (actAdb.getExpValue() >= randomVal)
				{				
					bestAd=actAdb;
					break;
				}
					
			}
			//if (bestAd!=null) ad=bestAd;
			
		}
		else
		{
		
			boolean found = false;
			while (it.hasNext()) 
			{
				bestAd = it.next();
				if (Integer.valueOf(bestAd.getType())!=99)
				{
					found = true;
					break;
				}
			}
			if(!found)
				bestAd = null;
		}
		 ad=bestAd;

		
    }
    public  void timerPause(){
    	
    		suspend= true;
    
	}
    public  void timerResume(){
    
    	  suspend = false;
    	
    }
    
    public  void timerStop(){
    	if (t!=null) t.cancel();
    }
public void getInnerAd(){
	getCurrAdd(true);
}

@Override
public void onAdsLoaded(AdsLoadEvent evt) {
	// TODO Auto-generated method stub
	getCurrAdd(false);
}
}
    